package xnum

import "math"

// 判断坐标点p是否在多边形dic区域内【坐标需要为统一坐标系坐标，即p和dic都是高德/百度/GPS等坐标】
//
//	p	要判断的坐标点
//	dic	多边形经纬度
func InDistance(p GPS, dic []GPS) bool {
	point_num := len(dic)
	if point_num <= 2 {
		// 格式化判断，坐标点最起码有三个才能判断在不在区域内，所以低于三个的此处直接返回false
		return false
	}
	// 循环点
	p1 := dic[0]
	p2 := dic[0]
	intersectCount := 0
	for i := 0; i < point_num; i++ {
		// 如果落在坐标点上，就直接返回true
		// PS: 因浮点数无法直接判断全等，所以此处使用IsEqualFloat来判断是否相等【相差低于归零位就认为相等】
		if IsEqualFloat(p.Latitude, dic[i].Latitude) && IsEqualFloat(p.Longitude, dic[i].Longitude) {
			return true
		}
		p2 = dic[i%point_num]
		if p.Latitude < math.Min(p1.Latitude, p2.Latitude) || p.Latitude > math.Max(p1.Latitude, p2.Latitude) {
			p1 = p2
			continue
		}
		if p.Latitude > math.Min(p1.Latitude, p2.Latitude) && p.Latitude < math.Max(p1.Latitude, p2.Latitude) {
			if p.Longitude <= math.Max(p1.Longitude, p2.Longitude) {
				if IsEqualFloat(p1.Latitude, p2.Latitude) && p.Longitude >= math.Min(p1.Longitude, p2.Longitude) {
					return true
				}

				if IsEqualFloat(p1.Longitude, p2.Longitude) {
					if IsEqualFloat(p1.Longitude, p.Longitude) {
						return true
					} else {
						intersectCount++
					}
				} else {
					xinters := (p.Latitude-p1.Latitude)*(p2.Longitude-p1.Longitude)/(p2.Latitude-p1.Latitude) + p1.Longitude
					if math.Abs(p.Longitude-xinters) < FLOAT_EQUAL_MIN {
						return true
					}

					if p.Longitude < xinters {
						intersectCount++
					}
				}
			}
		} else {
			if IsEqualFloat(p.Latitude, p2.Latitude) && p.Longitude <= p2.Longitude {
				p3 := dic[(i+1)%point_num]
				if p.Latitude >= math.Min(p1.Latitude, p3.Latitude) && p.Latitude <= math.Max(p1.Latitude, p3.Latitude) {
					intersectCount++
				} else {
					intersectCount += 2
				}
			}
		}
		p1 = p2
	}
	// 奇数在多边形内，偶数在多边形外。另此处使用位运算确定是否为奇数，返回为bool，所以可直接进行返回
	return intersectCount&1 == 1
}
